<?php

namespace App\Console\Commands\System\Project;

use App\Models\System\Project\SystemProjectModel;
use App\Models\System\Project\SystemProjectModuleModel;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;

class ProjectModuleGenerateCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'system:projectModuleGenerate';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '系统：生成项目模块记录';


    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }


    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle(): int
    {
        $systemProject = SystemProjectModel::query()->where("isDeleted", 0)->get();
        if ($systemProject->isEmpty()) {
            $this->error("请先添加项目信息后再重试");
            return parent::FAILURE;
        }
        $systemProjectStr    = $this->getProjectAskStr($systemProject);
        $projectId           = $this->getProjectId($systemProject, $systemProjectStr);
        $systemProjectModule = SystemProjectModuleModel::query()
                                                       ->where("projectId", $projectId)
                                                       ->orderByDesc("id")
                                                       ->get();

        $enName = $this->getEnName($projectId, $systemProjectModule);
        $cnName = $this->getCnName($projectId, $systemProjectModule);

        if ($systemProjectModule->isEmpty()) {
            $moduleCode = 1;
        } else {
            $moduleCode = ((int)$systemProjectModule->last()->moduleCode) + 1;
        }
        SystemProjectModuleModel::query()->insertGetId([
            "projectId"  => $projectId,
            "cnName"     => $cnName,
            "enName"     => $enName,
            "moduleCode" => str_pad(
                $moduleCode,
                3,
                "0",
                STR_PAD_LEFT
            ),
            "createdAt"  => time()
        ]);

        $this->info("添加项目模块 {$cnName} 成功!");
        return parent::SUCCESS;
    }

    /**
     * @return mixed
     */
    public function getEnName(int $projectId, Collection $systemProjectModule)
    {
        if (empty($enName = $this->ask('请输入模块英文名称标识'))) {
            $this->error("模块英文名称不能为空");
            return $this->getEnName($projectId, $systemProjectModule);
        }

        if (!preg_match("/^[a-z|A-Z][a-zA-Z_].*[a-z|A-Z]$/", $enName)) {
            $this->error("模块英文名称格式不正确（1、字母开头 2、仅包含英文字母和下划线 3、字母结尾）");
            return $this->getEnName($projectId, $systemProjectModule);
        }

        if ($systemProjectModule->where("enName", $enName)->first()) {
            $this->error("模块英文名称已存在");
            return $this->getEnName($projectId, $systemProjectModule);
        }
        return strtoupper($enName);
    }

    /**
     * @return mixed
     */
    public function getCnName(int $projectId, Collection $systemProjectModule)
    {
        if (empty($cnName = $this->ask('请输入模块中文名称标识'))) {
            $this->error("模块中文名称不能为空");
            return $this->getCnName($projectId, $systemProjectModule);
        }

        if ($systemProjectModule->where("cnName", $cnName)->first()) {
            $this->error("模块中文名称已存在");
            return $this->getCnName($projectId, $systemProjectModule);
        }
        return $cnName;
    }

    /**
     * @param Collection $systemProject
     * @return string
     */
    public function getProjectAskStr(Collection $systemProject): string
    {
        $systemProjectStr = "";
        $systemProject->each(function (SystemProjectModel $systemProjectModel, $key) use (
            &$systemProjectStr,
            $systemProject
        ) {
            $systemProjectStr .= vsprintf(" %s、 %s %s", [
                $systemProjectModel->id,
                $systemProjectModel->cnName,
                count($systemProject) == $key + 1 ? "" : PHP_EOL
            ]);
        });
        return $systemProjectStr;
    }

    /**
     * @param Collection $systemProject
     * @param string $systemProjectStr
     * @param bool $errorInput
     * @return mixed
     */
    public function getProjectId(Collection $systemProject, string $systemProjectStr, bool $errorInput = false)
    {
        if ($errorInput) {
            $this->error("输入有误");
        }
        $projectId = $this->ask(vsprintf("请选择以下项目， 输入对应数字 %s%s", [
            PHP_EOL,
            rtrim($systemProjectStr)
        ]));
        if ($systemProject->where("id", $projectId)->isEmpty()) {
            return $this->getProjectId($systemProject, $systemProjectStr, true);
        }
        return $projectId;
    }
}
